package com.lheia.proxy

import com.lheia.FailCountable
import org.apache.log4j.Logger
import us.codecraft.webmagic.Page
import us.codecraft.webmagic.Spider
import us.codecraft.webmagic.Task
import us.codecraft.webmagic.proxy.Proxy
import us.codecraft.webmagic.proxy.ProxyProvider
import us.codecraft.webmagic.proxy.SimpleProxyProvider

import java.util.concurrent.atomic.AtomicInteger

/**
 * 第一超过多少次失效的ip需要清理，第二重试在哪里设置
 */
class FileProxyProvider implements ProxyProvider {

    private static Logger logger = Logger.getLogger(FileProxyProvider.class);
    private String filePath = null
    private final int failCountThreshold = 0
    private final List<Proxy> proxies;
    private final AtomicInteger pointer;
    private boolean refresh

    FileProxyProvider(List<Proxy> proxies) {
        this(proxies, new AtomicInteger(-1));
    }

    FileProxyProvider(List<Proxy> proxies, String filePath, boolean refresh, int failCountThreshold) {
        this(proxies)
        this.filePath = filePath
        this.failCountThreshold = failCountThreshold
        this.refresh = refresh
    }

    private FileProxyProvider(List<Proxy> proxies, AtomicInteger pointer) {
        this.proxies = proxies;
        this.pointer = pointer;
    }

    static FileProxyProvider from(Proxy... proxies) {
        List<Proxy> proxiesTemp = new ArrayList<Proxy>(proxies.length);
        for (Proxy proxy : proxies) {
            proxiesTemp.add(proxy);
        }
        return new FileProxyProvider(Collections.unmodifiableList(proxiesTemp));
    }

    static FileProxyProvider from(String filePath, boolean refresh, int failCountThreshold) {
        def file = new File(filePath)
        List proxyList = new ArrayList<Proxy>()
        file.readLines().each {
            if (it.split(":").length == 2) {
                String ip = it.split(":")[0]
                String port = it.split(":")[1]
                proxyList << new FileProxy(ip, Integer.valueOf(port))
            } else {
                log.info("ip不合法，ip${it}")
            }
        }
        return new FileProxyProvider(proxyList, filePath, refresh, failCountThreshold)
    }

    @Override
    Proxy getProxy(Task task) {
        Proxy proxy =  proxies.get(incrForLoop())
        logger.info("-----!!!!!!!使用代理:"+proxy)
        return proxy
    }

    private int incrForLoop() {
        int p = pointer.incrementAndGet();
        int size = proxies.size();
        if (p < size) {
            return p;
        }
        while (!pointer.compareAndSet(p, p % size)) {
            p = pointer.get();
        }
        return p % size;
    }


    static FileProxyProvider from(String filePath) {
        return from(filePath, false,0)
    }


    @Override
    void returnProxy(Proxy proxy, Page page, Task task) {
        //判断page成功状态
        if (!page.isDownloadSuccess()) {
            logger.info("-----!!!!!!!错误代理"+proxy)
            FileProxy fileProxy = (FileProxy) proxy
            fileProxy.failIncrement()
            if (failCountThreshold > 0) {
                if (fileProxy.getFailCount() >= failCountThreshold) {
                    proxies.remove(fileProxy)
                    if(proxies.size() == 0){
                        if(task instanceof Spider)
                            task.stop()
                    }
                    p = pointer.get();
                    if(p >= proxies.size()){
                        while (!pointer.compareAndSet(p, p % size)){}
                    }
                }
                if (refresh) {
                    //待优化。。
                    File oldFile = new File(filePath)
                    File newFile = new File(filePath+task.UUID)
                    if(!newFile.exists()){
                        newFile.createNewFile()
                    }
                    def line = oldFile.getText()
                    newFile.setText(line.replaceAll(proxy.getHost()+":"+proxy.getPort()+"\n",""))
                    oldFile.delete()
                    newFile.renameTo(filePath)
                }
            }
        }
    }
}
